package cn.gx.kevin.service.impl;

import cn.gx.kevin.common.thread.DaoDBKeyHolder;
import cn.gx.kevin.common.utils.DynamicParameter;
import cn.gx.kevin.common.utils.PagingResult;
import cn.gx.kevin.dao.IBaseDao;
import cn.gx.kevin.dao.IDynamicDao;
import cn.gx.kevin.domain.DynamicCountParam;
import cn.gx.kevin.service.IBaseService;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: BaseService
 * @Description: 基本的增删改查业务类
 * @author hjwen
 * @date 2014-12-1 下午5:21:11
 * @param <T> 对应的领域实体类型
 * @param <K> 主键数据类型
 */
public abstract class BaseService<T extends Serializable, K extends Serializable> implements IBaseService<T, K> {


	@Autowired
	IDynamicDao dynamicDao;

	/**
	 * @Fields txManager : 用于编程方式，手工控制事务 DataSourceTransactionManager
	 *         JtaTransactionManager
	 */
	protected AbstractPlatformTransactionManager txManager;

	@Resource(name = "transactionManager")
	public void setTxManager(AbstractPlatformTransactionManager txManager) {
		this.txManager = txManager;
	}

	/**
	 * 切换到指定数据库
	 ***/
	protected void setDbKey(String key) {
		DaoDBKeyHolder.setKey(key);
	}

	/**
	 * 恢复到默认数据库
	 ***/
	protected void clearDbKey() {
		DaoDBKeyHolder.clear();
	}

	protected IBaseDao<T, K> dao;

	protected IBaseDao<T, K> getDao() {
		return this.dao;
	}

	public final Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 设置dao的抽象方法，子类必须实现，并设置好子类对应的dao,实现时，请采用spring注入
	 * 
	 * @param dao
	 */
	public abstract void setDao(IBaseDao<T, K> dao);


	@Override
	public <E> List<E> selectParamE(Map<String, Object> param) throws Exception {
		return getDao().selectParamE(param);
	}

	 /**
	 *  @param param  根据参数里指定的字段、条件查询结果，用于指定只查询某些字段，以提高查询性能，走selectOnfield sql配置
	 * List<String> selectFields 用户设置需要查询的字段，param.put("selectFields",selectFields);
	 * 条件：whereFields: param.put("whereFields",List<whereFields>);
	 * @return 符合条件记录的实体对象的List
	 */
	@Override
	public List<T> selectOnfield(Map<String, Object> param) throws Exception {
		// TODO Auto-generated method stub
		return this.dao.selectOnfield(param);
	}

	@Override
	public int countByDynamicParams(DynamicCountParam params) throws Exception{
		int count = this.dynamicDao.count(params);
		return count;
	}


	@Override
	public boolean uniqueValid(Map<String, Object> params) throws Exception {
		boolean isPast = true;
		int res = getDao().count(params);
		if (res > 0) {
			isPast = false;
		}
		return isPast;
	}
	@Override
	public  int insertNotNull(T entity) throws Exception{
		return getDao().insertNotNull(entity);
	}

	@Override
	public int insert(T entity) throws Exception {
		return getDao().insert(entity);
	}

	@Override
	public int update(T entity) throws Exception {
		return getDao().update(entity);
	}

	@Override
	public int updateParam(Map<String, Object> param) throws Exception {
		return getDao().updateParam(param);
	}

	@Override
	public int delete(K primaryKey) throws Exception {
		return getDao().delete(primaryKey);
	}

	@Override
	public int deleteList(List<K> list) throws Exception {
		for (K key : list) {
			this.delete(key);
		}
		return 0;
	}

	@Override
	public int deleteParam(Map<String, Object> param) throws Exception {
		return getDao().deleteParam(param);
	}

	@Override
	public int truncate() throws Exception {
		return getDao().truncate();
	}

	@Override
	public int countAll() throws Exception {
		return getDao().count(null);
	}

	@Override
	public int count(Map<String, Object> param) throws Exception {
		return getDao().count(param);
	}

	@Override
	public T get(K primaryKey) throws Exception {
		return getDao().get(primaryKey);
	}

	@Override
	public List<T> selectAll() throws Exception {
		return getDao().selectParam(null);
	}

	@Override
	public List<T> selectParam(Map<String, Object> param) throws Exception {
		return getDao().selectParam(param);
	}

	@Override
	public PagingResult<T> selectPagination(DynamicParameter param) throws Exception {
		return getDao().selectPagination(param);
	}

	@Override
	public void insertList(List<T> list) throws Exception {
		IBaseDao<T, K> dao = getDao();
		for (T t : list) {
			dao.insertNotNull(t);
		}
	}

	@Override
	public int insertBatch(List<T> list) throws Exception {
		return getDao().insertBatch(list);
	}

	@Override
	public int updateBatch(List<T> list) throws Exception {
		return getDao().updateBatch(list);
	}

	@Override
    public int deleteBatch(List<K> list) throws Exception {
        return getDao().deleteBatch(list);
    }

	@Override
	public Map<K, T> selectMap(Map<String, Object> param, String keyName) throws Exception {

		return getDao().selectMap(param, keyName);
	}

	@Override
	public Map<K, T> selectMap(Map<String, Object> param) throws Exception {
		return getDao().selectMap(param, "id");
	}

	@Override
	public Map<K, T> selectAllMap() throws Exception {
		return getDao().selectMap(null, "id");
	}

	@Override
	public Map<K, T> selectAllMap(String keyName) throws Exception {
		return getDao().selectMap(null, keyName);
	}


	public  List<List<T>> groupList(List<T> list,int subListLen) {
		List<List<T>> listGroup = new ArrayList<List<T>>();
		int listSize = list.size();
		int toIndex = subListLen;
		for (int i = 0; i < list.size(); i += subListLen) {
			if (i + subListLen > listSize) {
				toIndex = listSize - i;
			}
			List<T> newList = list.subList(i, i + toIndex);
			listGroup.add(newList);
		}
		return listGroup;
	}

	@Override
	public int batchInsert(List<T> list, int commitNum,Map<String, String[]> reqParams) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("开始导入数据");
		}
		int suceesful = 0;
		List<List<T>> array =	 groupList(list,commitNum);
		for(List<T> subList : array){
			suceesful = suceesful + this.insertBatch(subList);
		}
		if (logger.isDebugEnabled()) {
			logger.debug("导入数据结束");
		}
		return suceesful;
	}

	@Override
	public int batchUpdate(List<T> list, int commitNum,Map<String, String[]> reqParams) throws Exception {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int insertObject(Object entity) throws Exception {
		return this.insert((T) entity);
	}

	@Override
	public int updateObject(Object entity) throws Exception {
		return this.update((T) entity);
	}


	@Override
	public List<T> selectTop(int top, Map<String, Object> params, LinkedHashMap<String, String> orderMap) throws Exception {
		return this.dao.selectTop(top,params,orderMap);
	}



}
